
#include "appinc.h"


#ifndef HAVE_STRLCPY
size_t strlcpy(char *dest, const char *src, size_t dest_size)
{
	register char *d = dest;
	register const char *s = src;
	register size_t n = dest_size;

	/* Copy as many bytes as will fit */
	if (n != 0 && --n != 0) {
		do {
			if ((*d++ = *s++) == 0)
				break;
		} while (--n != 0);
	}

	/* Not enough room in dest, add NUL and traverse rest of src */
	if (n == 0) {
		if (dest_size != 0)
			*d = '\0'; /* NUL-terminate dest */
		while (*s++)
			;
	}

	return (s - src - 1); /* count does not include NUL */
}
#endif


/*将字符串转成大写*/
void libstr_toupper(char *str)
{
	while ('\0' != *str) {
		*str = toupper(*str);
		str++;
	}
} 

/*将字符串转成小写*/
void libstr_tolowr(char *str)
{
	while ('\0' != *str) {
		*str = tolower(*str);
		str++;
	}
} 


/*去掉字符串开始和结尾的回车、换行、空格、TAB */
void libstr_trim(char *a_line)
{
	char temp_line[1024];
	int i;

	memset(temp_line, 0x00, sizeof(temp_line));
	strlcpy(temp_line, a_line, sizeof(temp_line));
	i = strlen(temp_line);
	while (temp_line[ i - 1 ] == ' '  || temp_line[ i - 1 ] == '\r' ||
			temp_line[ i - 1 ] == '\n' || temp_line[ i - 1 ] == '\t') {
		temp_line[ i - 1 ] = 0;
		i--;
	}

	for (i = 0; ; i++) {
		if (!(temp_line[ i ] == ' '  || temp_line[ i ] == '\r' ||
			temp_line[ i ] == '\n' || temp_line[ i ] == '\t'))
			break;
	}

	strcpy(a_line, &temp_line[i]);
}

/* 移除行尾的\r、\n */
void libstr_del_crlf(char *line)
{
	char *str;
	int len;
	
	if (line == NULL)
		return;
	len = strlen(line);
	if (len <= 0)
		return;
	
	str = line + len - 1;
	while (*(str-1) && (*str == '\r' || *str == '\n'))
		*str-- = '\0';
}

/* 从路径中获取文件名 */
char *libstr_path_notdir(char *path)
{
	char *str;
	
	while (1) {
		str = strstr(path , "/");
		if (str == NULL)
			break;
		path = str+1;
	}

	return path;
}


/* 检查字符串是否是IPV4地址, 返回1表示是IPV4，反之不是 */
int libstr_is_ipv4(const char *ip)
{
	int dotcnt = 0, num;
	const char *cur = NULL;

	if (!ip)
		return 0;

	cur = ip;
	while (*cur) {
		if ('.' == *cur) {
			dotcnt++;
			num = atoi(cur);
			if (num < 0 || num > 255 || '.' == *(cur+1))
				return 0;
		} else if (*cur < '0' || *cur > '9') {
			return 0;
		}
		cur++;
	}

	if (dotcnt == 3)
		return 1;

	return 0;
}

int libstr_is_ipv6(const char *ip)
{
	int dotcnt = 0;
	int ip_len, i, j, temp_len;
	char temp[8];

	if (!ip)
		return 0;

	ip_len = strlen(ip);
	if (ip[ip_len-1] == ':')
		return 0;
	for (i = 0; i < ip_len; i++) {
		if(ip[i] == ':')
			dotcnt++;
	}
	if (dotcnt != 7)
		return 0;

	temp_len = 0;
	for (i = 0; i < ip_len; i++) {
		if (ip[i] != ':')
			temp[temp_len++] += ip[i];
		if (temp_len > 4)
			return 0;

		if (ip[i] == ':' || i == ip_len - 1) {
			if (temp_len == 0 || temp_len > 4)
				return 0;
			for (j = 0; j < temp_len; j++) {
				if (!(isdigit(temp[j]) || (temp[j] >= 'a' && temp[j] <= 'f') || (temp[j] >= 'A' && temp[j] <= 'F')))
				return 0;
			}
			temp_len = 0;
		}
	}
	
	return 1;
}



/* 检查字符串是否是IP地址, 返回1表示是IP，反之不是 */
int libstr_is_ip(const char *ip)
{
	int ret;

	ret = libstr_is_ipv4(ip);
	if (ret > 0)
		return ret;

	ret = libstr_is_ipv6(ip);
	if (ret > 0)
		return ret;

	return 0;
}


/* 检查字符串是否是IP地址+掩码, 返回1表示是IP，反之不是 */
int libstr_is_ip_mask(const char *ip_mask)
{
	char tmp_buf[32];
	char *str;
	int mask;

	if (!ip_mask)
		return 0;

	strlcpy(tmp_buf, ip_mask, sizeof(tmp_buf));
	str = strstr(tmp_buf, "/");
	if (str == NULL)
		return 0;
	*str++ = '\0';
	if (!libstr_is_ip(tmp_buf))
		return 0;
	mask = atoi(str);
	if (mask < 0 || mask > 32)
		return 0;

	return 1;
}



/* 检查字符串是否是MAC地址, 返回1表示是MAC，反之不是 */
int libstr_is_mac(const char *mac)
{
	int len = 0;
	int colon_cnt = 0;
	int snippet_cnt = 0;
	const char *st = mac;
	const char *cur = NULL;
	const char standard[] = {"0123456789:-abcdefABCDEF"};

	len = strlen(mac);
	if (len < 11 || len > 17)
		return 0;

	for (cur = st; *cur; cur++) {
		if (!strchr(standard, *cur))
			return 0;
		if (*cur == ':' || *cur == '-') {
			if (!isxdigit(*(cur+1)))
				return 0;
			if (snippet_cnt != 2 && snippet_cnt != 1)
				return 0;
			colon_cnt++;
			snippet_cnt = 0;
		} else {
			snippet_cnt++;
		}
	}

	if (colon_cnt != 5)
		return 0;

	return 1;
}


int libstr_mac_to_str(uint8_t *mac, char *str)
{
	if (mac == NULL || str == NULL)
		return -1;

	sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

	return 0;
}


/* 从字符串中获取IP和掩码, 返回0成功，其它失败 */
int libstr_get_ip_mask(const char *buf, char *ip, char *mask)
{
	char *tmp = NULL;
	char buf_bak[32];

	if (buf == NULL)
		return -1;
	
	strlcpy(buf_bak, buf, sizeof(buf_bak));
	
	tmp = strstr(buf_bak, "/");
	if (!tmp)
		return -1;

	*tmp = '\0';
	if (ip)
		strcpy(ip, buf_bak);
	*tmp = '/';
	tmp++;
	if (mask)
		strcpy(mask, tmp);

	return 0;
}


/* 获取字符串格式掩码长度 */
int libstr_mask_to_len(const char *smask)
{
	int i;
	struct in_addr addr;

	if (smask == NULL)
		return -EINVAL;

	if (inet_pton(AF_INET, smask, &addr) <= 0)
		return -EINVAL;
	for (i = 0; i < 32; i++) {
		if (!(ntohl(addr.s_addr) & (1<<(31-i))))
			break;
	}
	return i;
}


/* 检查一个字符串是否全部是数字, 如果是则返回1，否则返回0 */
int libstr_is_digit(const char *str)
{
	const char * p;
	p = str;
	if (p== NULL)
		return 0;
	
	while (*p != '\0') {
		if (*p < '0' || *p > '9')
			return 0;
		p++;
	}
	return 1;
}

/* 检查一个字符串是否为除空格以外的可打印字符, 如果是则返回1，否则返回0 */
int libstr_is_graph(const char *str)
{
	int len = 0;

	if (str == NULL)
		return 0;
	
	while (*str) {
		if (!isgraph(*str))
			return 0;
		str++;
		len++;
	}
	if (len == 0)
		return 0;
	return 1;
}


int libstr_str_to_hex(const char *str, uint8_t *hex)
{
	int i, size, len = 0;
	uint8_t result;
	
	if (!hex || !str)
		return -EINVAL;

	size = strlen(str);
	for (i = 0; i < size; i++) {
		if (isdigit(str[i]))
			result = str[i] - '0';
		else if (islower(str[i]))
			result = str[i] - 'a' + 10;
		else if (isupper(str[i]))
			result = str[i] - 'A' + 10;
		else if (str[i] == ' ' || str[i] == '\t')
			continue;
		else
			return -1;
		if (len%2)
			hex[i/2] |= result;
		else
			hex[i/2] = (result<<4);
		len++;
	}

	return len/2;
}


int libstr_hex_to_str(uint8_t *hex, uint32_t hex_len, char *str)
{
	uint8_t tmp;
	
	if (!hex || !str || !hex_len)
		return -1;

	while (hex_len--) {
		tmp = (*hex>>4)&0xF;
		if (tmp >= 0xA)
			*str++ = tmp - 0xA + 'A';
		else
			*str++ = tmp + '0';

		tmp = *hex++ & 0xf;
		if (tmp >= 0xA)
			*str++ = tmp - 0xA + 'A';
		else
			*str++ = tmp + '0';
	}
	*str = '\0';

	return 0;
}



/* 判读字符串口bool类型，返回0和1表示成功，其它表示失败 */
bool libstr_to_bool(const char *str, bool def)
{
	if (str == NULL)
		return def;
	
	if (!strcasecmp(str, "1") || !strcasecmp(str, "on") || !strcasecmp(str, "yes") || 
		!strcasecmp(str, "true") || !strcasecmp(str, "enable"))
		return true;
	if (!strcasecmp(str, "0") || !strcasecmp(str, "off") || !strcasecmp(str, "no") || 
		!strcasecmp(str, "false") || !strcasecmp(str, "disable"))
		return false;

	return def;
}


const char *libstr_get_postfix(const char *name)
{
	const char *str, *ret = NULL;

	str = name;
	while (str) {
		str = strchr(str, '.');
		if (str)
			ret = ++str;
	}

	return ret;
}

int libstr_cmp_prefix(const char *s1, const char *s2)
{
	if (s1 == NULL || s2 == NULL)
		return -EINVAL;
	
	if (s1 == s2)
		return 0;
	
	return strncmp(s1, s2, strlen(s2));

}
